#include "DHD_EventSystem.h"


void DHD_EventSystem::RegisterClient(EVENTID eventID, IListener* pClient)
{

	if (!pClient || AlreadyRegistered(eventID, pClient))	return;

	m_ClientDatabase.insert( make_pair(eventID, pClient) );
}

//	Unregister Client
void DHD_EventSystem::UnregisterClient(EVENTID eventID, IListener *pClient)
{
	
	pair<multimap<EVENTID, IListener*>::iterator,
		 multimap<EVENTID, IListener*>::iterator> range;

	range = m_ClientDatabase.equal_range(eventID);


	for(multimap<EVENTID, IListener*>::iterator mmIter = range.first;
					mmIter != range.second; mmIter++)
	{

		if((*mmIter).second == pClient)
		{

			mmIter = m_ClientDatabase.erase(mmIter);
			break;
		}
	}
}

//	Unregister Client All
void DHD_EventSystem::UnregisterClientAll(IListener *pClient)
{
	multimap<string, IListener*>::iterator mmIter = m_ClientDatabase.begin();

	while(mmIter !=m_ClientDatabase.end())
	{
		if((*mmIter).second == pClient)
		{
			mmIter = m_ClientDatabase.erase(mmIter);
		}
		else
			mmIter++;
	}
}

//	Dispatch Event.
void DHD_EventSystem::DispatchEvent(CEvent *pEvent)
{
	
	pair<multimap<EVENTID, IListener*>::iterator,
		 multimap<EVENTID, IListener*>::iterator> range;

	
	range = m_ClientDatabase.equal_range(pEvent->GetEventID());


	for(multimap<EVENTID, IListener*>::iterator mmIter = range.first;
					mmIter != range.second; mmIter++)
	{

		(*mmIter).second->HandleEvent(pEvent);
	}
}

bool DHD_EventSystem::AlreadyRegistered(EVENTID eventID, IListener* pClient)
{
	bool bIsAlreadyRegistered = false;


	pair<multimap<EVENTID, IListener*>::iterator,
		 multimap<EVENTID, IListener*>::iterator> range;

	
	range = m_ClientDatabase.equal_range(eventID);

	
	for(multimap<EVENTID, IListener*>::iterator mmIter = range.first;
					mmIter != range.second; mmIter++)
	{

		if((*mmIter).second == pClient)
		{
			bIsAlreadyRegistered = true;
			break;
		}
	}

	return bIsAlreadyRegistered;
}


void DHD_EventSystem::SendEvent(EVENTID eventID, void* pData)
{
	CEvent newEvent(eventID, pData);

	m_CurrentEvents.push_back(newEvent);
}

void DHD_EventSystem::ProcessEvents(void)
{
	while(m_CurrentEvents.size())
	{
		DispatchEvent(&m_CurrentEvents.front());
		m_CurrentEvents.pop_front();
	}
}

void DHD_EventSystem::ClearEvents(void)
{
	m_CurrentEvents.clear();
}

void DHD_EventSystem::ShutdownEventSystem(void)
{
	m_ClientDatabase.clear();
}
